{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 任务3 特征工程&特征选择(3天)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 特征工程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#核心代码举例\n",
    "\n",
    "# 统计特征\n",
    "    #计算均值\n",
    "    gp = train.groupby(by)[fea].mean()\n",
    "    #计算中位数\n",
    "    gp = train.groupby(by)[fea].median()\n",
    "    #计算方差\n",
    "    gp = train.groupby(by)[fea].std()\n",
    "    #计算最大值\n",
    "    gp = train.groupby(by)[fea].max()\n",
    "    #计算最小值\n",
    "    gp = train.groupby(by)[fea].min()\n",
    "    #计算出现次数\n",
    "    gp = train.groupby(by)[fea].size()\n",
    "    \n",
    "\n",
    "# groupby生成统计特征：mean,std\n",
    "    # 按照communityName分组计算面积的均值和方差\n",
    "    temp = data.groupby('communityName')['area'].agg({'com_area_mean': 'mean', 'com_area_std': 'std'})\n",
    "\n",
    "# 特征拆分\n",
    "    # 将houseType转为'Room'，'Hall'，'Bath'\n",
    "    def Room(x):\n",
    "        Room = int(x.split('室')[0])\n",
    "        return Room\n",
    "    def Hall(x):\n",
    "        Hall = int(x.split(\"室\")[1].split(\"厅\")[0])\n",
    "        return Hall\n",
    "    def Bath(x):\n",
    "        Bath = int(x.split(\"室\")[1].split(\"厅\")[1].split(\"卫\")[0])\n",
    "        return Bath\n",
    "\n",
    "    data['Room'] = data['houseType'].apply(lambda x: Room(x))\n",
    "    data['Hall'] = data['houseType'].apply(lambda x: Hall(x))\n",
    "    data['Bath'] = data['houseType'].apply(lambda x: Bath(x))\n",
    "    \n",
    "#特征合并\n",
    "    # 合并部分配套设施特征\n",
    "    data['trainsportNum'] = 5 * data['subwayStationNum'] / data['subwayStationNum'].mean() + data['busStationNum'] / \\\n",
    "                                                                                             data[\n",
    "                                                                                                 'busStationNum'].mean()\n",
    "\n",
    "# 交叉生成特征:特征之间交叉+ - * / \n",
    "data['Room_Bath'] = (data['Bath']+1) / (data['Room']+1)\n",
    "\n",
    "\n",
    "# 聚类特征\n",
    "from sklearn.mixture import GaussianMixture  使用GaussianMixture做聚类特征\n",
    "gmm = GaussianMixture(n_components=4, covariance_type='full', random_state=0)\n",
    "gmm.fit_predict(data)\n",
    " \n",
    "# 特征编码\n",
    "from sklearn.preprocessing import LabelEncoder\n",
    "data['communityName'] = LabelEncoder().fit_transform(data['communityName'])\n",
    "from sklearn import preprocessing.OneHotEncoder\n",
    "data['communityName'] = OneHotEncoder().fit_transform(data['communityName'])\n",
    "\n",
    "\n",
    "# 过大量级值取log平滑（针对线性模型有效）\n",
    "data[feature]=np.log1p(data[feature])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-12-24T13:40:19.692972Z",
     "start_time": "2019-12-24T13:40:19.126469Z"
    }
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "from sklearn.preprocessing import LabelEncoder\n",
    "\n",
    "train = pd.read_csv('./train_data.csv')\n",
    "test = pd.read_csv('./test_a.csv')\n",
    "target_train = train.pop('tradeMoney')\n",
    "target_test = test.pop('tradeMoney')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 特征合并"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-12-24T13:40:55.454321Z",
     "start_time": "2019-12-24T13:40:55.291756Z"
    }
   },
   "outputs": [],
   "source": [
    "def newfeature(data):\n",
    "\n",
    "\n",
    "    # 将houseType转为'Room'，'Hall'，'Bath'\n",
    "    def Room(x):\n",
    "        Room = int(x.split('室')[0])\n",
    "        return Room\n",
    "    def Hall(x):\n",
    "        Hall = int(x.split(\"室\")[1].split(\"厅\")[0])\n",
    "        return Hall\n",
    "    def Bath(x):\n",
    "        Bath = int(x.split(\"室\")[1].split(\"厅\")[1].split(\"卫\")[0])\n",
    "        return Bath\n",
    "\n",
    "    data['Room'] = data['houseType'].apply(lambda x: Room(x))\n",
    "    data['Hall'] = data['houseType'].apply(lambda x: Hall(x))\n",
    "    data['Bath'] = data['houseType'].apply(lambda x: Bath(x))\n",
    "    data['Room_Bath'] = (data['Bath']+1) / (data['Room']+1)\n",
    "    # 填充租房类型\n",
    "    data.loc[(data['rentType'] == '未知方式') & (data['Room'] <= 1), 'rentType'] = '整租'\n",
    "    # print(data.loc[(data['rentType']=='未知方式')&(data['Room_Bath']>1),'rentType'])\n",
    "    data.loc[(data['rentType'] == '未知方式') & (data['Room_Bath'] > 1), 'rentType'] = '合租'\n",
    "    data.loc[(data['rentType'] == '未知方式') & (data['Room'] > 1) & (data['area'] < 50), 'rentType'] = '合租'\n",
    "    data.loc[(data['rentType'] == '未知方式') & (data['area'] / data['Room'] < 20), 'rentType'] = '合租'\n",
    "    # data.loc[(data['rentType']=='未知方式')&(data['area']>60),'rentType']='合租'\n",
    "    data.loc[(data['rentType'] == '未知方式') & (data['area'] <= 50) & (data['Room'] == 2), 'rentType'] = '合租'\n",
    "    data.loc[(data['rentType'] == '未知方式') & (data['area'] > 60) & (data['Room'] == 2), 'rentType'] = '整租'\n",
    "    data.loc[(data['rentType'] == '未知方式') & (data['area'] <= 60) & (data['Room'] == 3), 'rentType'] = '合租'\n",
    "    data.loc[(data['rentType'] == '未知方式') & (data['area'] > 60) & (data['Room'] == 3), 'rentType'] = '整租'\n",
    "    data.loc[(data['rentType'] == '未知方式') & (data['area'] >= 100) & (data['Room'] > 3), 'rentType'] = '整租'\n",
    "\n",
    "    # data.drop('Room_Bath', axis=1, inplace=True)\n",
    "    # 提升0.0001\n",
    "    def month(x):\n",
    "        month = int(x.split('/')[1])\n",
    "        return month\n",
    "    # def day(x):\n",
    "    #     day = int(x.split('/')[2])\n",
    "    #     return day\n",
    "    # 结果变差\n",
    "\n",
    "    # 分割交易时间\n",
    "    # data['year']=data['tradeTime'].apply(lambda x:year(x))\n",
    "    data['month'] = data['tradeTime'].apply(lambda x: month(x))\n",
    "    # data['day'] = data['tradeTime'].apply(lambda x: day(x))# 结果变差\n",
    "    #     data['pv/uv'] = data['pv'] / data['uv']\n",
    "    #     data['房间总数'] = data['室'] + data['厅'] + data['卫']\n",
    "\n",
    "    # 合并部分配套设施特征\n",
    "    data['trainsportNum'] = 5 * data['subwayStationNum'] / data['subwayStationNum'].mean() + data['busStationNum'] / \\\n",
    "                                                                                             data[\n",
    "                                                                                                 'busStationNum'].mean()\n",
    "    data['all_SchoolNum'] = 2 * data['interSchoolNum'] / data['interSchoolNum'].mean() + data['schoolNum'] / data[\n",
    "        'schoolNum'].mean() \\\n",
    "                            + data['privateSchoolNum'] / data['privateSchoolNum'].mean()\n",
    "    data['all_hospitalNum'] = 2 * data['hospitalNum'] / data['hospitalNum'].mean() + \\\n",
    "                              data['drugStoreNum'] / data['drugStoreNum'].mean()\n",
    "    data['all_mall'] = data['mallNum'] / data['mallNum'].mean() + \\\n",
    "                       data['superMarketNum'] / data['superMarketNum'].mean()\n",
    "    data['otherNum'] = data['gymNum'] / data['gymNum'].mean() + data['bankNum'] / data['bankNum'].mean() + \\\n",
    "                       data['shopNum'] / data['shopNum'].mean() + 2 * data['parkNum'] / data['parkNum'].mean()\n",
    "\n",
    "    data.drop(['subwayStationNum', 'busStationNum',\n",
    "               'interSchoolNum', 'schoolNum', 'privateSchoolNum',\n",
    "               'hospitalNum', 'drugStoreNum', 'mallNum', 'superMarketNum', 'gymNum', 'bankNum', 'shopNum', 'parkNum'],\n",
    "              axis=1, inplace=True)\n",
    "    # 提升0.0005\n",
    "    \n",
    "#     data['houseType_1sumcsu']=data['Bath'].map(lambda x:str(x))+data['month'].map(lambda x:str(x))\n",
    "#     data['houseType_2sumcsu']=data['Bath'].map(lambda x:str(x))+data['communityName']\n",
    "#     data['houseType_3sumcsu']=data['Bath'].map(lambda x:str(x))+data['plate']\n",
    "    \n",
    "    data.drop('houseType', axis=1, inplace=True)\n",
    "    data.drop('tradeTime', axis=1, inplace=True)\n",
    "    \n",
    "    data[\"area\"] = data[\"area\"].astype(int)\n",
    "\n",
    "\n",
    "    # categorical_feats = ['rentType', 'houseFloor', 'houseToward', 'houseDecoration', 'communityName','region', 'plate']\n",
    "    categorical_feats = ['rentType', 'houseFloor', 'houseToward', 'houseDecoration',  'region', 'plate','cluster']\n",
    "\n",
    "    return data, categorical_feats"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 计算统计特征"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-12-24T13:41:02.458588Z",
     "start_time": "2019-12-24T13:41:00.981539Z"
    }
   },
   "outputs": [],
   "source": [
    "#计算统计特征\n",
    "def featureCount(train,test):\n",
    "    train['data_type'] = 0\n",
    "    test['data_type'] = 1\n",
    "    data = pd.concat([train, test], axis=0, join='outer')\n",
    "    def feature_count(data, features=[]):\n",
    "        new_feature = 'count'\n",
    "        for i in features:\n",
    "            new_feature += '_' + i\n",
    "        temp = data.groupby(features).size().reset_index().rename(columns={0: new_feature})\n",
    "        data = data.merge(temp, 'left', on=features)\n",
    "        return data\n",
    "\n",
    "    data = feature_count(data, ['communityName'])\n",
    "    data = feature_count(data, ['buildYear'])\n",
    "    data = feature_count(data, ['totalFloor'])\n",
    "    data = feature_count(data, ['communityName', 'totalFloor'])\n",
    "    data = feature_count(data, ['communityName', 'newWorkers'])\n",
    "    data = feature_count(data, ['communityName', 'totalTradeMoney'])\n",
    "    new_train = data[data['data_type'] == 0]\n",
    "    new_test = data[data['data_type'] == 1]\n",
    "    new_train.drop('data_type', axis=1, inplace=True)\n",
    "    new_test.drop(['data_type'], axis=1, inplace=True)\n",
    "    return new_train, new_test\n",
    "    \n",
    "train, test = featureCount(train, test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## groupby方法生成统计特征"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-12-24T13:41:05.546332Z",
     "start_time": "2019-12-24T13:41:04.242821Z"
    }
   },
   "outputs": [],
   "source": [
    "#groupby生成统计特征：mean,std等\n",
    "\n",
    "def gourpby(train,test):\n",
    "    train['data_type'] = 0\n",
    "    test['data_type'] = 1\n",
    "    data = pd.concat([train, test], axis=0, join='outer')\n",
    "    columns = ['rentType', 'houseFloor', 'houseToward', 'houseDecoration', 'communityName', 'region', 'plate']\n",
    "    for feature in columns:\n",
    "        data[feature] = LabelEncoder().fit_transform(data[feature])\n",
    "\n",
    "    temp = data.groupby('communityName')['area'].agg({'com_area_mean': 'mean', 'com_area_std': 'std'})\n",
    "    temp.fillna(0, inplace=True)\n",
    "    data = data.merge(temp, on='communityName', how='left')\n",
    "    \n",
    "    data['price_per_area'] = data.tradeMeanPrice / data.area * 100\n",
    "    temp = data.groupby('communityName')['price_per_area'].agg(\n",
    "        {'comm_price_mean': 'mean', 'comm_price_std': 'std'})\n",
    "    temp.fillna(0, inplace=True)\n",
    "    data = data.merge(temp, on='communityName', how='left')\n",
    "   \n",
    "    temp = data.groupby('plate')['price_per_area'].agg(\n",
    "        {'plate_price_mean': 'mean', 'plate_price_std': 'std'})\n",
    "    temp.fillna(0, inplace=True)\n",
    "    data = data.merge(temp, on='plate', how='left')\n",
    "    data.drop('price_per_area', axis=1, inplace=True)\n",
    "\n",
    "    temp = data.groupby('plate')['area'].agg({'plate_area_mean': 'mean', 'plate_area_std': 'std'})\n",
    "    temp.fillna(0, inplace=True)\n",
    "    data = data.merge(temp, on='plate', how='left')\n",
    "    \n",
    "    temp = data.groupby(['plate'])['buildYear'].agg({'plate_year_mean': 'mean', 'plate_year_std': 'std'})\n",
    "    data = data.merge(temp, on='plate', how='left')\n",
    "    data.plate_year_mean = data.plate_year_mean.astype('int')\n",
    "    data['comm_plate_year_diff'] = data.buildYear - data.plate_year_mean\n",
    "    data.drop('plate_year_mean', axis=1, inplace=True)\n",
    "\n",
    "    temp = data.groupby('plate')['trainsportNum'].agg('sum').reset_index(name='plate_trainsportNum')\n",
    "    data = data.merge(temp, on='plate', how='left')\n",
    "    temp = data.groupby(['communityName', 'plate'])['trainsportNum'].agg('sum').reset_index(name='com_trainsportNum')\n",
    "    data = data.merge(temp, on=['communityName', 'plate'], how='left')\n",
    "    data['trainsportNum_ratio'] = list(map(lambda x, y: round(x / y, 3) if y != 0 else -1,\n",
    "                                           data['com_trainsportNum'], data['plate_trainsportNum']))\n",
    "    data = data.drop(['com_trainsportNum', 'plate_trainsportNum'], axis=1)\n",
    "\n",
    "    temp = data.groupby('plate')['all_SchoolNum'].agg('sum').reset_index(name='plate_all_SchoolNum')\n",
    "    data = data.merge(temp, on='plate', how='left')\n",
    "    temp = data.groupby(['communityName', 'plate'])['all_SchoolNum'].agg('sum').reset_index(name='com_all_SchoolNum')\n",
    "    data = data.merge(temp, on=['communityName', 'plate'], how='left')\n",
    "    data = data.drop(['com_all_SchoolNum', 'plate_all_SchoolNum'], axis=1)\n",
    "\n",
    "    temp = data.groupby(['communityName', 'plate'])['all_mall'].agg('sum').reset_index(name='com_all_mall')\n",
    "    data = data.merge(temp, on=['communityName', 'plate'], how='left')\n",
    "\n",
    "    temp = data.groupby('plate')['otherNum'].agg('sum').reset_index(name='plate_otherNum')\n",
    "    data = data.merge(temp, on='plate', how='left')\n",
    "    temp = data.groupby(['communityName', 'plate'])['otherNum'].agg('sum').reset_index(name='com_otherNum')\n",
    "    data = data.merge(temp, on=['communityName', 'plate'], how='left')\n",
    "    data['other_ratio'] = list(map(lambda x, y: round(x / y, 3) if y != 0 else -1,\n",
    "                                   data['com_otherNum'], data['plate_otherNum']))\n",
    "    data = data.drop(['com_otherNum', 'plate_otherNum'], axis=1)\n",
    "\n",
    "    temp = data.groupby(['month', 'communityName']).size().reset_index(name='communityName_saleNum')\n",
    "    data = data.merge(temp, on=['month', 'communityName'], how='left')\n",
    "    temp = data.groupby(['month', 'plate']).size().reset_index(name='plate_saleNum')\n",
    "    data = data.merge(temp, on=['month', 'plate'], how='left')\n",
    "\n",
    "    data['sale_ratio'] = round((data.communityName_saleNum + 1) / (data.plate_saleNum + 1), 3)\n",
    "    data['sale_newworker_differ'] = 3 * data.plate_saleNum - data.newWorkers\n",
    "    data.drop(['communityName_saleNum', 'plate_saleNum'], axis=1, inplace=True)\n",
    "\n",
    "    new_train = data[data['data_type'] == 0]\n",
    "    new_test = data[data['data_type'] == 1]\n",
    "    new_train.drop('data_type', axis=1, inplace=True)\n",
    "    new_test.drop(['data_type'], axis=1, inplace=True)\n",
    "    return new_train, new_test\n",
    "\n",
    "train, test = gourpby(train, test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-12-24T13:38:33.198959Z",
     "start_time": "2019-12-24T13:38:33.193970Z"
    }
   },
   "source": [
    "## 聚类方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-12-24T13:41:25.894916Z",
     "start_time": "2019-12-24T13:41:25.241666Z"
    }
   },
   "outputs": [],
   "source": [
    "#聚类\n",
    "def cluster(train,test):\n",
    "    from sklearn.mixture import GaussianMixture\n",
    "\n",
    "    train['data_type'] = 0\n",
    "    test['data_type'] = 1\n",
    "    data = pd.concat([train, test], axis=0, join='outer')\n",
    "    col = ['totalFloor',\n",
    "           'houseDecoration', 'communityName', 'region', 'plate', 'buildYear',\n",
    "\n",
    "           'tradeMeanPrice', 'tradeSecNum', 'totalNewTradeMoney',\n",
    "           'totalNewTradeArea', 'tradeNewMeanPrice', 'tradeNewNum', 'remainNewNum',\n",
    "\n",
    "           'landTotalPrice', 'landMeanPrice', 'totalWorkers',\n",
    "           'newWorkers', 'residentPopulation', 'lookNum',\n",
    "           'trainsportNum',\n",
    "           'all_SchoolNum', 'all_hospitalNum', 'all_mall', 'otherNum']\n",
    "\n",
    "    # EM\n",
    "    gmm = GaussianMixture(n_components=3, covariance_type='full', random_state=0)\n",
    "    data['cluster']= pd.DataFrame(gmm.fit_predict(data[col]))\n",
    "\n",
    "\n",
    "    col1 = ['totalFloor','houseDecoration', 'communityName', 'region', 'plate', 'buildYear']\n",
    "    col2 = ['tradeMeanPrice', 'tradeSecNum', 'totalNewTradeMoney',\n",
    "            'totalNewTradeArea', 'tradeNewMeanPrice', 'tradeNewNum', 'remainNewNum',\n",
    "            'landTotalPrice', 'landMeanPrice', 'totalWorkers',\n",
    "            'newWorkers', 'residentPopulation', 'lookNum',\n",
    "            'trainsportNum',\n",
    "            'all_SchoolNum', 'all_hospitalNum', 'all_mall', 'otherNum']\n",
    "    for feature1 in col1:\n",
    "        for feature2 in col2:\n",
    "        \n",
    "            temp = data.groupby(['cluster',feature1])[feature2].agg('mean').reset_index(name=feature2+'_'+feature1+'_cluster_mean')\n",
    "            temp.fillna(0, inplace=True)\n",
    "       \n",
    "            data = data.merge(temp, on=['cluster', feature1], how='left')\n",
    "    \n",
    "   \n",
    "    new_train = data[data['data_type'] == 0]\n",
    "    new_test = data[data['data_type'] == 1]\n",
    "    new_train.drop('data_type', axis=1, inplace=True)\n",
    "    new_test.drop(['data_type'], axis=1, inplace=True)\n",
    "    \n",
    "    return new_train, new_test\n",
    "\n",
    "train, test = cluster(train, test)   "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## log平滑"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 过大量级值取log平滑（针对线性模型有效）\n",
    "big_num_cols = ['totalTradeMoney','totalTradeArea','tradeMeanPrice','totalNewTradeMoney', 'totalNewTradeArea',\n",
    "                'tradeNewMeanPrice','remainNewNum', 'supplyNewNum', 'supplyLandArea',\n",
    "                'tradeLandArea','landTotalPrice','landMeanPrice','totalWorkers','newWorkers',\n",
    "                'residentPopulation','pv','uv']\n",
    "for col in big_num_cols:\n",
    "        train[col] = train[col].map(lambda x: np.log1p(x))\n",
    "        test[col] = test[col].map(lambda x: np.log1p(x))\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#对比特征工程前后线性模型结果情况\n",
    "test=test.fillna(0)\n",
    "# Lasso回归\n",
    "from sklearn.linear_model import Lasso\n",
    "lasso=Lasso(alpha=0.1)\n",
    "lasso.fit(train,target_train)\n",
    "#预测测试集和训练集结果\n",
    "y_pred_train=lasso.predict(train)\n",
    "y_pred_test=lasso.predict(test)\n",
    "\n",
    "#对比结果\n",
    "from sklearn.metrics import r2_score\n",
    "score_train=r2_score(y_pred_train,target_train)\n",
    "print(\"训练集结果：\",score_train)\n",
    "score_test=r2_score(y_pred_test, target_test)\n",
    "print(\"测试集结果：\",score_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-12-24T12:31:08.989972Z",
     "start_time": "2019-12-24T12:31:08.986978Z"
    }
   },
   "source": [
    "# 特征选择"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "from sklearn.preprocessing import LabelEncoder\n",
    "#读取数据\n",
    "train = pd.read_csv('')\n",
    "test = pd.read_csv('')\n",
    "\n",
    "target_train = train.pop('tradeMoney')\n",
    "target_test = test.pop('tradeMoney')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 相关系数法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#相关系数法特征选择\n",
    "from sklearn.feature_selection import SelectKBest\n",
    "\n",
    "print(train.shape)\n",
    "\n",
    "sk=SelectKBest(k=150)\n",
    "new_train=sk.fit_transform(train,target_train)\n",
    "print(new_train.shape)\n",
    "\n",
    "# 获取对应列索引\n",
    "select_columns=sk.get_support(indices = True)\n",
    "# print(select_columns)\n",
    "\n",
    "# 获取对应列名\n",
    "# print(test.columns[select_columns])\n",
    "select_columns_name=test.columns[select_columns]\n",
    "new_test=test[select_columns_name]\n",
    "print(new_test.shape)\n",
    "# Lasso回归\n",
    "from sklearn.linear_model import Lasso\n",
    "\n",
    "lasso=Lasso(alpha=0.1)\n",
    "lasso.fit(new_train,target_train)\n",
    "#预测测试集和训练集结果\n",
    "y_pred_train=lasso.predict(new_train)\n",
    "\n",
    "y_pred_test=lasso.predict(new_test)\n",
    "\n",
    "#对比结果\n",
    "from sklearn.metrics import r2_score\n",
    "score_train=r2_score(y_pred_train,target_train)\n",
    "print(\"训练集结果：\",score_train)\n",
    "score_test=r2_score(y_pred_test, target_test)\n",
    "print(\"测试集结果：\",score_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Wrapper"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Wrapper\n",
    "\n",
    "from sklearn.feature_selection import RFE\n",
    "from sklearn.linear_model import LinearRegression\n",
    "lr = LinearRegression()\n",
    "rfe = RFE(lr, n_features_to_select=160)\n",
    "rfe.fit(train,target_train)\n",
    "\n",
    "RFE(estimator=LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None,\n",
    "                               normalize=False),\n",
    "    n_features_to_select=40, step=1, verbose=0)\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "select_columns = [f for f, s in zip(train.columns, rfe.support_) if s]\n",
    "print(select_columns)\n",
    "new_train = train[select_columns]\n",
    "new_test = test[select_columns]\n",
    "\n",
    "# Lasso回归\n",
    "from sklearn.linear_model import Lasso\n",
    "\n",
    "lasso=Lasso(alpha=0.1)\n",
    "lasso.fit(new_train,target_train)\n",
    "#预测测试集和训练集结果\n",
    "y_pred_train=lasso.predict(new_train)\n",
    "\n",
    "y_pred_test=lasso.predict(new_test)\n",
    "\n",
    "#对比结果\n",
    "from sklearn.metrics import r2_score\n",
    "score_train=r2_score(y_pred_train,target_train)\n",
    "print(\"训练集结果：\",score_train)\n",
    "score_test=r2_score(y_pred_test, target_test)\n",
    "print(\"测试集结果：\",score_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Embedded\n",
    "### 基于惩罚项的特征选择法\n",
    "### Lasso(l1)和Ridge(l2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Embedded\n",
    "# 基于惩罚项的特征选择法\n",
    "# Lasso(l1)和Ridge(l2)\n",
    "\n",
    "from sklearn.linear_model import Ridge\n",
    "\n",
    "ridge = Ridge(alpha=5)\n",
    "ridge.fit(train,target_train)\n",
    "\n",
    "Ridge(alpha=5, copy_X=True, fit_intercept=True, max_iter=None, normalize=False,\n",
    "      random_state=None, solver='auto', tol=0.001)\n",
    "\n",
    "# 特征系数排序\n",
    "coefSort = ridge.coef_.argsort()\n",
    "print(coefSort)\n",
    "\n",
    "\n",
    "# 特征系数\n",
    "featureCoefSore=ridge.coef_[coefSort]\n",
    "print(featureCoefSore)\n",
    "\n",
    "\n",
    "select_columns = [f for f, s in zip(train.columns, featureCoefSore) if abs(s)> 0.0000005 ] \n",
    "# 选择绝对值大于0.0000005的特征\n",
    "\n",
    "new_train = train[select_columns]\n",
    "new_test = test[select_columns]\n",
    "# Lasso回归\n",
    "from sklearn.linear_model import Lasso\n",
    "\n",
    "lasso=Lasso(alpha=0.1)\n",
    "lasso.fit(new_train,target_train)\n",
    "#预测测试集和训练集结果\n",
    "y_pred_train=lasso.predict(new_train)\n",
    "\n",
    "y_pred_test=lasso.predict(new_test)\n",
    "\n",
    "#对比结果\n",
    "from sklearn.metrics import r2_score\n",
    "score_train=r2_score(y_pred_train,target_train)\n",
    "print(\"训练集结果：\",score_train)\n",
    "score_test=r2_score(y_pred_test, target_test)\n",
    "print(\"测试集结果：\",score_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 基于树模型的特征选择法\n",
    "### 随机森林 平均不纯度减少（mean decrease impurity"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Embedded\n",
    "# 基于树模型的特征选择法\n",
    "# 随机森林 平均不纯度减少（mean decrease impurity\n",
    "\n",
    "\n",
    "from sklearn.ensemble import RandomForestRegressor\n",
    "rf = RandomForestRegressor()\n",
    "# 训练随机森林模型，并通过feature_importances_属性获取每个特征的重要性分数。rf = RandomForestRegressor()\n",
    "rf.fit(train,target_train)\n",
    "print(\"Features sorted by their score:\")\n",
    "print(sorted(zip(map(lambda x: round(x, 4), rf.feature_importances_), train.columns),\n",
    "             reverse=True))\n",
    "\n",
    "select_columns = [f for f, s in zip(train.columns, rf.feature_importances_) if abs(s)> 0.00005 ] \n",
    "# 选择绝对值大于0.00005的特征\n",
    "\n",
    "new_train = train[select_columns]\n",
    "new_test = test[select_columns]\n",
    "\n",
    "# Lasso回归\n",
    "from sklearn.linear_model import Lasso\n",
    "\n",
    "lasso=Lasso(alpha=0.1)\n",
    "lasso.fit(new_train,target_train)\n",
    "#预测测试集和训练集结果\n",
    "y_pred_train=lasso.predict(new_train)\n",
    "\n",
    "y_pred_test=lasso.predict(new_test)\n",
    "\n",
    "#对比结果\n",
    "from sklearn.metrics import r2_score\n",
    "score_train=r2_score(y_pred_train,target_train)\n",
    "print(\"训练集结果：\",score_train)\n",
    "score_test=r2_score(y_pred_test, target_test)\n",
    "print(\"测试集结果：\",score_test)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "307.2px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
